import json
from typing import Dict, List, Optional,Any
from datetime import datetime, timedelta
from demo.models.schemas import DeviceInfo, WebSocketMessage
from like.websocket.schemas import BindRequest


class DeviceManager:
    def __init__(self):
        self.devices: Dict[str, DeviceInfo] = {}
        self.connected_websockets: Dict[str, Any] = {}
        self.message_history: List[WebSocketMessage] = []

    async def register_device(self, device_info: DeviceInfo) -> bool:
        """注册设备"""
        try:
            self.devices[device_info.DeviceId] = device_info
            print(f"设备注册成功: {device_info.DeviceId}")
            return True
        except Exception as e:
            print(f"设备注册失败: {e}")
            return False

    def update_device_status(self, device_id: str, is_online: bool, is_used: bool = None):
        """更新设备状态"""
        if device_id in self.devices:
            self.devices[device_id].IsOnline = is_online
            self.devices[device_id].last_heartbeat = datetime.now()
            if is_used is not None:
                self.devices[device_id].IsUsed = is_used
            print(f"设备状态更新: {device_id} - 在线: {is_online}")

    async def handle_websocket_message(self, device_id: str, message: str):
        """处理WebSocket消息"""
        try:
            message_data = json.loads(message)
            ws_message = WebSocketMessage(
                type=message_data.get("type", "unknown"),
                device_id=device_id,
                data=message_data.get("data", {}),
                timestamp=datetime.now()
            )

            self.message_history.append(ws_message)

            # 限制历史消息数量
            if len(self.message_history) > 1000:
                self.message_history = self.message_history[-1000:]

            # 处理心跳消息
            if ws_message.type == "heartbeat":
                self.update_device_status(device_id, True)
                await self.broadcast_to_monitors({
                    "type": "heartbeat",
                    "device_id": device_id,
                    "timestamp": ws_message.timestamp.isoformat()
                })

            print(f"收到来自 {device_id} 的消息: {ws_message.type}")
            return ws_message

        except json.JSONDecodeError as e:
            print(f"消息解析失败: {e}")
            return None

    async def broadcast_to_monitors(self, message: dict):
        """向监控客户端广播消息"""
        disconnected = []
        for client_id, websocket in self.connected_websockets.items():
            try:
                await websocket.send_text(json.dumps(message))
            except Exception as e:
                print(f"向监控客户端 {client_id} 发送消息失败: {e}")
                disconnected.append(client_id)

        # 清理断开的连接
        for client_id in disconnected:
            del self.connected_websockets[client_id]

    async def send_to_device(self, device_id: str, message: dict):
        """向特定设备发送消息"""
        if device_id in self.connected_websockets:
            try:
                await self.connected_websockets[device_id].send_text(json.dumps(message))
                return True
            except Exception as e:
                print(f"向设备 {device_id} 发送消息失败: {e}")
                return False
        return False

    def get_device_info(self, device_id: str) -> Optional[DeviceInfo]:
        """获取设备信息"""
        return self.devices.get(device_id)

    def get_all_devices(self) -> List[DeviceInfo]:
        """获取所有设备信息"""
        return list(self.devices.values())

    def get_online_devices(self) -> List[DeviceInfo]:
        """获取在线设备"""
        return [device for device in self.devices.values() if device.IsOnline]

    async def cleanup_offline_devices(self, timeout_minutes: int = 5):
        """清理超时离线设备"""
        current_time = datetime.now()
        offline_devices = []

        for device_id, device in self.devices.items():
            if (device.last_heartbeat and
                    current_time - device.last_heartbeat > timedelta(minutes=timeout_minutes)):
                device.IsOnline = False
                offline_devices.append(device_id)

        if offline_devices:
            print(f"标记为离线的设备: {offline_devices}")
            await self.broadcast_to_monitors({
                "type": "devices_offline",
                "device_ids": offline_devices
            })

    async def handle_bind_request(self, device_id: str, data: Dict[str, Any]):
        """处理绑定请求"""
        platform_id = data.get("platform_id")
        if platform_id:
            bind_request = BindRequest(
                device_id=device_id,
                platform_id=platform_id,
                bind_config=data.get("bind_config")
            )
            # binding = await binding_manager.bind_device_to_platform(bind_request)
            # if binding:
            #     # 通知设备绑定成功
            #     await self.send_to_device(device_id, {
            #         "type": "bind_success",
            #         "platform_id": platform_id,
            #         "binding_id": binding.binding_id
            #     })
            #
            #     # 广播绑定信息
            #     await self.broadcast_to_monitors({
            #         "type": "device_bound",
            #         "device_id": device_id,
            #         "platform_id": platform_id,
            #         "binding_id": binding.binding_id
            #     })


# 全局设备管理器实例
device_manager = DeviceManager()